use anyhow::{Context, Result};
use arboard::Clipboard;
use eframe::{egui, NativeOptions};
use image::{DynamicImage, GenericImageView};
use rqrr::PreparedImage;
use screenshots::Screen;

#[cfg(windows)]
use winapi::um::wincon::FreeConsole;

/// 二维码扫描应用主结构体
struct QRCodeScannerApp {
    selected_area: Option<(f32, f32, f32, f32)>, // (x, y, width, height)
    screenshot: Option<DynamicImage>,            // 当前截取的屏幕图像
    decoded_text: Option<String>,                // 解码后的二维码内容
    error_message: Option<String>,               // 错误信息
    is_selecting: bool,                          // 是否正在选择区域
    start_pos: Option<egui::Pos2>,               // 选择区域的起始位置
}

impl Default for QRCodeScannerApp {
    fn default() -> Self {
        Self {
            selected_area: None,
            screenshot: None,
            decoded_text: None,
            error_message: None,
            is_selecting: false,
            start_pos: None,
        }
    }
}

impl eframe::App for QRCodeScannerApp {
    /// 主界面更新函数
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("二维码扫描工具");
            ui.add_space(10.0);

            // 操作按钮区域
            ui.horizontal(|ui| {
                if ui.button("📷 截取屏幕").clicked() {
                    self.take_screenshot();
                }
                
                if ui.button("🗑️ 清除").clicked() {
                    self.clear_all();
                }
                
                if ui.button("📋 复制到剪贴板").clicked() {
                    if let Some(text) = &self.decoded_text {
                        if let Err(e) = self.copy_to_clipboard(text) {
                            self.error_message = Some(format!("复制失败: {}", e));
                        } else {
                            self.error_message = Some("已复制到剪贴板!".to_string());
                        }
                    }
                }
            });

            ui.add_space(10.0);

            // 显示错误信息
            if let Some(error) = &self.error_message {
                ui.colored_label(egui::Color32::RED, error);
                ui.add_space(5.0);
            }

            // 显示解码结果
            if let Some(text) = &self.decoded_text {
                ui.label("扫描结果:");
                ui.text_edit_multiline(&mut text.as_str());
                ui.add_space(10.0);
            }

            // 显示截图和选择区域
            if let Some(screenshot) = &self.screenshot {
                let size = screenshot.dimensions();
                let max_width = ui.available_width() - 20.0;
                let max_height = 400.0;
                
                // 计算缩放比例以适应界面
                let scale = (max_width / size.0 as f32).min(max_height / size.1 as f32);
                let display_width = size.0 as f32 * scale;
                let display_height = size.1 as f32 * scale;

                let (response, painter) = ui.allocate_painter(
                    egui::vec2(display_width, display_height),
                    egui::Sense::click_and_drag(),
                );

                // 将截图转换为 egui 可显示的格式
                let rgba_img = screenshot.to_rgba8();
                let pixels: Vec<egui::Color32> = rgba_img
                    .pixels()
                    .map(|p| egui::Color32::from_rgba_premultiplied(p[0], p[1], p[2], p[3]))
                    .collect();

                let color_image = egui::ColorImage {
                    size: [size.0 as usize, size.1 as usize],
                    pixels,
                };

                let texture = ctx.load_texture("screenshot", color_image, Default::default());
                painter.image(
                    texture.id(),
                    egui::Rect::from_min_size(
                        response.rect.min,
                        egui::vec2(display_width, display_height),
                    ),
                    egui::Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)),
                    egui::Color32::WHITE,
                );

                // 处理鼠标拖拽选择区域
                if response.drag_started() {
                    self.is_selecting = true;
                    self.start_pos = Some(response.hover_pos().unwrap());
                }

                if response.dragged() && self.is_selecting {
                    if let Some(start_pos) = self.start_pos {
                        if let Some(current_pos) = response.hover_pos() {
                            let rect = egui::Rect::from_two_pos(start_pos, current_pos);
                            
                            // 绘制红色选择框
                            painter.rect_stroke(rect, 0.0, (2.0, egui::Color32::RED));
                            
                            // 将界面坐标转换为原始图像坐标
                            let x = (rect.min.x - response.rect.min.x) / scale;
                            let y = (rect.min.y - response.rect.min.y) / scale;
                            let width = rect.width() / scale;
                            let height = rect.height() / scale;
                            
                            self.selected_area = Some((x, y, width, height));
                        }
                    }
                }

                if response.drag_released() {
                    self.is_selecting = false;
                    self.start_pos = None;
                    
                    // 释放鼠标时自动扫描选中区域
                    if let Some(area) = self.selected_area {
                        self.scan_selected_area(area);
                    }
                }

                // 显示已选择的区域（绿色边框）
                if let Some(area) = self.selected_area {
                    let rect = egui::Rect::from_min_size(
                        egui::pos2(
                            response.rect.min.x + area.0 * scale,
                            response.rect.min.y + area.1 * scale,
                        ),
                        egui::vec2(area.2 * scale, area.3 * scale),
                    );
                    painter.rect_stroke(rect, 0.0, (2.0, egui::Color32::GREEN));
                }
            }

            // 使用说明
            ui.add_space(10.0);
            ui.collapsing("使用说明", |ui| {
                ui.label("1. 点击 '📷 截取屏幕' 按钮截取当前屏幕");
                ui.label("2. 在截图上拖拽选择包含二维码的区域");
                ui.label("3. 释放鼠标后自动扫描二维码");
                ui.label("4. 点击 '📋 复制到剪贴板' 复制结果");
                ui.label("5. 点击 '🗑️ 清除' 重新开始");
            });
        });
    }
}

impl QRCodeScannerApp {
    /// 截取当前屏幕
    fn take_screenshot(&mut self) {
        match Screen::all() {
            Ok(screens) => {
                if let Some(screen) = screens.first() {
                    match screen.capture() {
                        Ok(image) => {
                            // 将截图转换为 DynamicImage 格式
                            let img = DynamicImage::ImageRgba8(
                                image::RgbaImage::from_raw(
                                    image.width(),
                                    image.height(),
                                    image.to_vec(),
                                ).unwrap(),
                            );
                            self.screenshot = Some(img);
                            self.selected_area = None;
                            self.decoded_text = None;
                            self.error_message = None;
                        }
                        Err(e) => {
                            self.error_message = Some(format!("截图失败: {}", e));
                        }
                    }
                } else {
                    self.error_message = Some("未找到屏幕".to_string());
                }
            }
            Err(e) => {
                self.error_message = Some(format!("获取屏幕信息失败: {}", e));
            }
        }
    }

    /// 扫描选中区域的二维码
    fn scan_selected_area(&mut self, area: (f32, f32, f32, f32)) {
        if let Some(screenshot) = &self.screenshot {
            let (x, y, width, height) = area;
            
            // 确保坐标在有效范围内
            let img_width = screenshot.width() as f32;
            let img_height = screenshot.height() as f32;
            
            let x = x.max(0.0).min(img_width - 1.0) as u32;
            let y = y.max(0.0).min(img_height - 1.0) as u32;
            let width = width.max(1.0).min(img_width - x as f32) as u32;
            let height = height.max(1.0).min(img_height - y as f32) as u32;
            
            // 裁剪选中区域
            let cropped = screenshot.crop_imm(x, y, width, height);
            
            // 扫描二维码并更新结果
            match self.scan_qr_code(&cropped) {
                Ok(text) => {
                    self.decoded_text = Some(text);
                    self.error_message = None;
                }
                Err(e) => {
                    self.error_message = Some(format!("扫描失败: {}", e));
                    self.decoded_text = None;
                }
            }
        }
    }

    /// 扫描图像中的二维码
    fn scan_qr_code(&self, img: &DynamicImage) -> Result<String> {
        // 转换为灰度图像以提高检测准确性
        let gray_img = img.to_luma8();
        
        // 准备图像用于二维码检测
        let mut prepared = PreparedImage::prepare(gray_img);
        
        // 检测二维码网格
        let grids = prepared.detect_grids();
        
        if grids.is_empty() {
            anyhow::bail!("未在图像中检测到二维码");
        }
        
        // 解码第一个检测到的二维码
        let grid = &grids[0];
        let content = grid.decode()
            .with_context(|| "无法解码二维码内容")?;
        
        Ok(content.1)
    }

    /// 复制文本到剪贴板
    fn copy_to_clipboard(&self, text: &str) -> Result<()> {
        let mut clipboard = Clipboard::new()
            .with_context(|| "无法访问剪贴板")?;
        
        clipboard.set_text(text)
            .with_context(|| "无法复制文本到剪贴板")?;
        
        Ok(())
    }

    /// 清除所有数据
    fn clear_all(&mut self) {
        self.selected_area = None;
        self.screenshot = None;
        self.decoded_text = None;
        self.error_message = None;
        self.is_selecting = false;
        self.start_pos = None;
    }
}

/// 程序入口点
fn main() -> Result<()> {
    // 在 Windows 上隐藏控制台窗口
    #[cfg(windows)]
    unsafe {
        FreeConsole();
    }

    let options = NativeOptions {
        viewport: egui::ViewportBuilder::default()
            .with_inner_size([800.0, 600.0])
            .with_min_inner_size([600.0, 400.0]),
        ..Default::default()
    };

    eframe::run_native(
        "二维码扫描工具",
        options,
        Box::new(|cc| {
            // 配置中文字体支持
            let mut fonts = egui::FontDefinitions::default();
            
            // 添加中文字体
            fonts.font_data.insert(
                "chinese".to_owned(),
                egui::FontData::from_static(include_bytes!("../assets/fonts/Alibaba-PuHuiTi-Regular.ttf")),
            );
            
            // 将中文字体设置为优先字体
            fonts.families
                .get_mut(&egui::FontFamily::Proportional)
                .unwrap()
                .insert(0, "chinese".to_owned());
            
            cc.egui_ctx.set_fonts(fonts);
            
            Box::new(QRCodeScannerApp::default())
        }),
    ).map_err(|e| anyhow::anyhow!("GUI启动失败: {}", e))?;

    Ok(())
}
